#    Copyright (C) 2007, Maxime Biais <maxime@biais.org>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

from datautils import sort_by
from svgdata import points_group, point_rect, line, grid, header, footer
import math

class SVGOut:
    def __init__(self, fileout, data,
             xopts={"index": 0, "steps": 5, "size": 5, "func": lambda x:x},
             yopts={"index": 1, "steps": 0.01, "size": 5, "func": lambda x:x},
             pcolor="#00f", maxw=0, maxh=0):
        self.fileout = fileout
        self.xopts = xopts
        self.yopts = yopts
        self.data = data
        self.pcolor = pcolor
        self.maxw = maxw
        self.maxh = maxh

    def __getitem__(self, a):
        return getattr(self, a)

    def _h_w(self):
        self.w, mw = self._calc_size(self.xopts)
        self.h, mh = self._calc_size(self.yopts)
        if self.maxw:
            self.xopts["steps"] = self.maxw / float(mw)
            self.w = self.maxw
        if self.maxh:
            self.yopts["steps"] = self.maxh / float(mh)
            self.h = self.maxh

    def _calc_size(self, opts):
        self.sorteddata = sort_by(self.data, opts["index"])
        min = opts["func"](self.sorteddata[0][opts["index"]])
        max = opts["func"](self.sorteddata[-1][opts["index"]])
        return (max - min) * opts["steps"], max

    def out(self):
        head = header % self
        sgrid = grid % self
        points = []
        for p in self.data:
            hp = self.xopts["size"]
            wp = self.xopts["size"]
            x = self.xopts["func"](p[self.xopts["index"]]) * \
                                     self.xopts["steps"] - hp / 2
            y = self.yopts["func"](p[self.yopts["index"]]) * \
                                     self.yopts["steps"] - wp / 2
            color = self.pcolor
            points.append(point_rect % locals())
        points = "\n".join(points)
        w, h = self.w, self.h
        group = points_group % locals()
        foot = footer % self
        self.towrite = "%(head)s%(sgrid)s%(group)s%(foot)s" % locals()

    def write(self):
        stream = open(self.fileout, "w")
        stream.write(self.towrite)
        stream.close()

    def __str__(self):
        return "(%d, %d)" % (self.w, self.h)

def chart(data, fileout):
    s = SVGOut(fileout, data, maxw=700, maxh=400)
    s._h_w()
    s.out()
    s.write()
